/**
 *  Copyright 2002-2009 the original author or authors.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package foo.bar.wiki.security;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.authz.permission.WildcardPermission;

import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

/**
 * An extension of JSecurity's {@link org.apache.shiro.authz.permission.WildcardPermission} that
 * provides methods to :-
 *
 * <ul>
 *  <li>get & set the domain part</li>
 *  <li>get & set the action part</li>
 *  <li>get & set the instance part</li>
 *  <li>access the permission as String eg. "domain:action:instance" </li>
 * </ul>
 *
 * @author tmjee
 * @version $Date: 2009-03-14 14:53:07 +0800 (Sat, 14 Mar 2009) $ $Id$
 */
public class ExtendedWildcardPermission extends WildcardPermission {

    private static final Log LOG = LogFactory.getLog(ExtendedWildcardPermission.class);


    public ExtendedWildcardPermission(String wildcardString) {
        super(wildcardString);
    }

    public ExtendedWildcardPermission(String wildcardString, boolean caseSensitive) {
        super(wildcardString, caseSensitive);
    }

    public ExtendedWildcardPermission(Set<String> domainParts, Set<String> actionParts, Set<String> instanceParts) {
        super("*:*:*");
        setDomainPart(domainParts);
        setActionParts(actionParts);
        setInstanceParts(instanceParts);
    }

    protected void setDomainPart(Set<String> domainParts) {
        getParts().set(0, domainParts);
    }

    public Set<String> getDomainParts() {
        if (getParts().size() >= 1) {
            return new LinkedHashSet<String>(getParts().get(0));
        }
        return Collections.EMPTY_SET;
    }

    protected void setActionParts(Set<String> actionParts) {
        getParts().set(1, actionParts);
    }

    public Set<String> getActionParts() {
        if (getParts().size() >= 2) {
            return new LinkedHashSet<String>(getParts().get(1));
        }
        return Collections.EMPTY_SET;
    }

    protected void setInstanceParts(Set<String> instanceParts) {
        getParts().set(2, instanceParts);
    }

    public Set<String> getInstanceParts() {
        if (getParts().size() >= 3) {
            return new LinkedHashSet<String>(getParts().get(2));
        }
        return Collections.EMPTY_SET;
    }

    public List<Set<String>> getParts() {
        return super.getParts();
    }


    public String permissionAsString() {
        // domain Part;
        String domainPart = "";
        if (getDomainParts().size() <= 0 ) {
            domainPart = domainPart + WILDCARD_TOKEN;
        }
        else {
            int totalDomainParts = getDomainParts().size();
            int currentDomainPartCount = 1;
            for (String _domainPart : getDomainParts()) {
                domainPart = domainPart + _domainPart;
                if (currentDomainPartCount < totalDomainParts) {
                    domainPart = domainPart + ",";
                }
                currentDomainPartCount++;
            }
        }

        // action part
        String actionPart = "";
        if (getActionParts().size() <= 0) {
            actionPart = actionPart + WILDCARD_TOKEN;
        }
        else {
            int totalActionParts = getActionParts().size();
            int currentActionPartCount = 1;
            for (String _actionPart : getActionParts()) {
                actionPart = actionPart + _actionPart;
                if (currentActionPartCount < totalActionParts) {
                    actionPart = actionPart + ",";
                }
                currentActionPartCount++;
            }
        }

        // instance part
        String instancePart = "";
        if (getInstanceParts().size() <= 0) {
            instancePart = instancePart + WILDCARD_TOKEN;
        }
        else {
            int totalInstancePart = getInstanceParts().size();
            int currentInstancePartCount = 1;
            for (String _instancePart: getInstanceParts()) {
                instancePart = instancePart + _instancePart;
                if (currentInstancePartCount < totalInstancePart) {
                    instancePart = instancePart + ",";
                }
                currentInstancePartCount++;
            }
        }

        return (domainPart+":"+actionPart+":"+instancePart);
    }




    /*public boolean implies(Permission p) {
        if (getDomainParts().contains("<>")) {
        //if (getInstanceParts().contains("ownership") && (!getInstanceParts().contains(WILDCARD_TOKEN))) {
            if (ownershipResolver != null) {
                return ownershipResolver.impliedOwnership(
                        getDomainParts(),
                        getActionParts(),
                        getInstanceParts(),
                        (User) SecurityUtils.getSubject().getPrincipal(),
                        (String) ThreadContext.get("_____domainId"),
                        (String) ThreadContext.get("_____domainType")
                );
            }
            else {
                LOG.info("ExtendedWildcardPermissionOwnershipResolver is null");
            }
        }
        else {
            LOG.info("instance part doesn't contains ownership, ExtendedWildcardPermissionOwnershipResolver will not kick in");
        }
        return super.implies(p);
    }*/
}
